package cn.wolfcode.job;


import cn.wolfcode.common.exception.BusinessException;
import cn.wolfcode.common.web.CodeMsg;
import cn.wolfcode.common.web.Result;
import cn.wolfcode.domain.SeckillProductVo;
import cn.wolfcode.fegin.SecKillProductFeignApi;
import cn.wolfcode.redis.JobRedisKey;
import cn.wolfcode.redis.SeckillRedisKey;
import com.alibaba.fastjson.JSON;
import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 用于处理用户缓存的定时任务
 * 为了保证Redis中的内存的有效使用。
 * 我们默认保留7天内的用户缓存数据，每天凌晨的时候会把7天前的用户登录缓存数据删除掉
 */
@Component
@Setter
@Getter
@RefreshScope
@Slf4j
public class SecKillProductJob implements SimpleJob {
    @Value("${job.seckillProduct.corn}")
    private String cron;
    @Value("${job.seckillProduct.shardingParameter}")
    private String shardingParameter;
    @Value("${job.seckillProduct.shardingCount}")
    private Integer shardingCount;
    @Value("${job.seckillProduct.dataFlow}")
    private boolean dataFlow;
    @Autowired
    private SecKillProductFeignApi secKillProductFeignApi;
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public void execute(ShardingContext shardingContext) {
        String time = shardingContext.getShardingParameter();
        Result<List<SeckillProductVo>> result = secKillProductFeignApi.selectTodayListByTime(Integer.valueOf(time));

        if (result.hasError() || result.getData()==null){
            log.warn("[秒杀商品数据预热] 查询秒杀商品数据失败，远程服务异常，res={}",JSON.toJSONString(result));
        }

        String key = JobRedisKey.SECKILL_PRODUCT_LIST.join(time);
        redisTemplate.delete(key);

        //设置 redis  缓存过期时间
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 30);

        long endTime = calendar.getTime().getTime();
        long remain = (endTime - new Date().getTime()) / 1000;

        List<SeckillProductVo> seckillProductVos = result.getData();
        log.warn("[秒杀商品预热] 准备开始预热秒杀商品数据，当前场次：{}，本次缓存数据：{}",time,seckillProductVos.size());
        //将遍历vo集合 将数据保存到redis中
        //key=TODAY:SECKILL:PRODUCTS:{TIME}
        //value={json}
        for (SeckillProductVo secKillProductVo : seckillProductVos) {
            String jsonVo = JSON.toJSONString(secKillProductVo);
            redisTemplate.opsForList().rightPush(JobRedisKey.SECKILL_PRODUCT_LIST.join(secKillProductVo.getTime() + ""), jsonVo);
            // 将库存余数存入Redis
            String stockCountKey = SeckillRedisKey.SECKILL_STOCK_COUNT_HASH.join(secKillProductVo.getTime() + "");
            redisTemplate.opsForHash().put(stockCountKey, secKillProductVo.getId() + "", secKillProductVo.getStockCount()+"");
            // 设置过期时间为当天的 23：30
            redisTemplate.expire(stockCountKey, remain, TimeUnit.SECONDS);
        }
    }
}
